package com.example.zzy.zzytest.data.structure.stack;


/**
 * 栈实现计算器
 * 两个栈
 * 1.遍历中缀表达式，数直接入数栈，
 * op的话需要peek现有op栈，如果栈顶操作符大于等于现有的，则需要数栈弹2，op栈弹1去计算，计算结果入数栈，当前op入op栈
 * 如果栈顶操作符小于等于扫描的，则扫描到的入栈
 * 2.扫描完之后，分别弹2数1op计算后入数栈，直到数栈中剩余1个元素为止
 * <p>
 * 中缀算数，只能算+m-n+k-l这样的，连续减会算不对
 */
public class Caculator {
    public static void main(String[] args) {
        //String calcText = "7*2*2-5+1-5+3-4";//如果是加一个减一个就正确，连续减会出错
        String calcText = "34+5*6-";

        CalcArrayStack numStack = new CalcArrayStack(10);
        CalcArrayStack opStack = new CalcArrayStack(10);
        int num1, num2, op;

        for (int i = 0; i < calcText.length(); i++) {
            char c = calcText.charAt(i);
            if (isOp(c)) {
                int peek = opStack.peek();
                if (priority(peek) >= priority(c)) {
                    num1 = numStack.popStack();
                    num2 = numStack.popStack();
                    op = opStack.popStack();
                    numStack.pushStack(calc(num1, num2, op));
                    opStack.pushStack(c);
                } else {
                    opStack.pushStack(c);
                }
            } else {
                numStack.pushStack(Character.getNumericValue(c));
            }
        }

        while (!opStack.isEmpty()) {
            op = opStack.popStack();
            num1 = numStack.popStack();
            num2 = numStack.popStack();
            numStack.pushStack(calc(num1, num2, op));
        }
        System.out.println("最后结果>>>" + numStack.popStack());
    }

    public static int calc(int num1, int num2, int op) {
        if (op == '+') return num1 + num2;
        if (op == '-') return num2 - num1;
        if (op == '*') return num1 * num2;
        if (op == '/') return num2 / num1;
        else return Integer.MIN_VALUE;
    }

    public static boolean isOp(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    public static int priority(int c) {
        if (c == '*' || c == '/') {
            return 1;
        } else if (c == '+' || c == '-') {
            return 0;
        } else {
            return -1;
        }
    }


}


class CalcArrayStack {
    private int maxSize;
    private int[] stack;
    private int top = -1;

    public CalcArrayStack(int maxSize) {
        this.maxSize = maxSize;
        this.stack = new int[maxSize];
    }

    //看栈顶
    public int peek() {
        if (!isEmpty()) {
            return this.stack[top];
        } else {
            System.out.println("栈为空");
            return Integer.MIN_VALUE;
        }

    }

    //栈满
    public boolean isFull() {
        return top == maxSize - 1;
    }

    //栈空
    public boolean isEmpty() {
        return top == -1;
    }

    //入栈
    public void pushStack(int num) {
        if (isFull()) {
            System.out.println("栈已满，入栈失败");
            return;
        }
        top++;
        this.stack[top] = num;
    }

    //出栈
    public int popStack() {
        if (isEmpty()) {
            System.out.println("栈为空，出栈失败");
            return Integer.MIN_VALUE;
        }
        int num = this.stack[top--];
        return num;
    }

    //遍历
    public void list() {
        for (int i = top; i >= 0; i--) {
            System.out.println(this.stack[i] + "\t");
        }
    }
}
